<?php

/**
 * **********************************************************
 * Librairie AutoDLJob
 * **********************************************************
 * Mandatory properties to define in job file :
 * --------------------------------------------
 * 	URL_SRC_HTML				- PreProcess HTML download file.
 * 	XPATH_VIDEO_DIRECT_LNK		- XPath Query to get link to dl value
 * 	PATH_TMP					- Path of temporary dir.
 * 	FILENAME_TMP_STEP_PRE		- Pattern of PreProcess file
 * 	FILENAME_TMP_STEP_RUN		- Pattern of saving dl main run part
 * 	FILENAME_TMP_STEP_POST		- Pattern remove of file name before PostProcessing
 * 	URL_RUN_FILE_PATTERN		- ?
 * 	RUN_TARGET_PATH				- Target path for recording file
 * 	RUN_REAL_DL					- Dev Flag to real to the dl part.
 *  POST_TARGET_PATH			- Final target directory
 * **********************************************************
 * @author PoLuX 
 */

// Dependencies
include_file('src/02_class/AJob.abstract_class.php');
include_file('src/02_class/tools/DownloadFile.tool_class.php');
include_file('src/02_class/tools/HTMLDocXPathQuerying.tool_class.php');

/** 
 * Class AutoDLJob - Specific Job Class
 * 
 * @author polux
 */
class AutoDLJob extends AJob implements IRunnableJob, IPreProcessedJob, IPostProcessedJob {
	
	// *********************** Private Attribute  *********************** //	
	/**
	 * Filepath of file after preprocessing step
	 * @var string
	 * @access private
	 */
	private $_s_fileHTML_step1;
	/**
	 * Filepaths of files after running step
	 * @var array(string)
	 * @access private
	 */
	private $_as_links_step2;
	
	/**
	 * URLs to download
	 * @var array(string)
	 */
	private $_as_filename_step3;
	
	// *********************** Default constructor *********************** //
	/**
	 * Constructor 
	 * 
	 * @param string 	$p_s_jobName			Job Name
	 * @param string 	$p_s_filepathJobDef		Filepath Job definition
	 */
	public function __construct($p_s_jobName,$p_s_filepathJobDef) {
		parent::__construct ($p_s_jobName,$p_s_filepathJobDef);
	}
	
	// *********************** Methods *********************** //
	/**
	 * setProperties - add AutoDLJob class properties
	 * 
	 * @see AJob::setProperties()
	 */
	public function setProperties()
	{
		
		// Common part
		$this->_as_propertiesLabel[]="JOB_PATH_TMP";
		// PRE Part
		$this->_as_propertiesLabel[]="JOBPRE_URL_HTML_FILE";
		$this->_as_propertiesLabel[]="JOBPRE_XPATH_DIRECT_LNK";
		$this->_as_propertiesLabel[]="JOBPRE_FILENAME_TMP_HTML";
		
		$this->_as_propertiesLabel[]="JOBPRE_EXCLUDE_FILE_EXISTING";
		
		// RUN 
		$this->_as_propertiesLabel[]="JOBRUN_FILENAME_TMP_STEP_RUN";
		$this->_as_propertiesLabel[]="JOBRUN_TARGET_PATH";
		$this->_as_propertiesLabel[]="JOBRUN_REAL_DL";
		
		// POST 
		$this->_as_propertiesLabel[]="JOBPOST_TARGET_PATH";	
		$this->_as_propertiesLabel[]="JOBPOST_FILEPATTERN_TO_REMOVE";
		
	}
	// *********************** Workflow Methods  *********************** //
	/**
	 * PreProcessJob - Pre Processing - Get HTML Source files & execute XSL on it.
	 * (non-PHPdoc)
	 * @see IPreProcessedJob::PreProcessJob()
	 */
	function PreProcessJob()
	{
		JobsManager::getLogManager()->addLogTitle("Pre-processing - START - Getting HTML File & execute XSL on it.");
		
		try
		{
			// SubStep 1 - Download HTML File
			// ==========================================================================
			
			// Log starting
			JobsManager::getLogManager()->addLogSubTitle("SubStep 1 - Download HTML File");			
				
			// Setting URL
			$l_s_url = $this->getPropertieValue("JOBPRE_URL_HTML_FILE");
			JobsManager::getLogManager()->addLogInformation($this,"URL to download : '$l_s_url'.");

			// Prepare Temp Directory
			php_jobs_launcher::prepareDir($this->getPropertieValue("JOB_PATH_TMP"),true);
				
			// Generate filename from HTML temporary file
			$this->_s_fileHTML_step1 = $this->getPropertieValue("JOB_PATH_TMP").str_replace("%d", date("Y_m_d-h:i"), $this->getPropertieValue("JOBPRE_FILENAME_TMP_HTML"));
						
			// Download HTML Main HTML
			try {
				// Instanciate new Job tool object
				$l_o_objTool = new DownloadFileJobTool($this);
				
				$l_as_options = array();
				$l_as_options["INPUT_URL"] = $l_s_url;
				$l_as_options["OUPUT_FILEPATH"] = $this->_s_fileHTML_step1;
				$l_as_options["POST_DATA"] = array();
				
				JobsManager::getLogManager()->addLogInformation($this,"Download of '".$l_s_url."' will start !");
				
				$l_o_objTool->RunJobTool($l_as_options);
				
				JobsManager::getLogManager()->addLogInformation($this,"File downloaded successfully to '".$this->_s_fileHTML_step1."'.");
			}
			catch (JobToolGenericException $e)
			{
				throw new JobGenericException("Error during a JTool execution :".$e->getMessage());
			}
			
			// SubStep 2 - Filter HTML with XPath query
			// ==========================================================================
				
			// Log starting
			JobsManager::getLogManager()->addLogBreak();
			JobsManager::getLogManager()->addLogSubTitle("SubStep 2 - Filter HTML with XPath query");
			// Filter HTML with XPath query
			$l_s_xpathQry = $this->getPropertieValue("JOBPRE_XPATH_DIRECT_LNK");
			try{
				// Instanciate new Job tool object
				$l_o_objTool = new HTMLDocXPathQuerying($this);
				
				$l_as_options = array();
				$l_as_options["INPUT_FILE"] = $this->_s_fileHTML_step1;
				$l_as_options["XPATH_QUERY"] = $l_s_xpathQry;
				
				JobsManager::getLogManager()->addLogInformation($this,"XPath Querying of HTML file (qry:$l_s_xpathQry)!");
				$this->_as_links_step2 = $l_o_objTool->RunJobTool($l_as_options);
				JobsManager::getLogManager()->addLogInformation($this,"Items founded : ".count($this->_as_links_step2).".");
			}
			catch (JobToolGenericException $e)
			{
				throw new JobGenericException("Error during a JTool execution :".$e->getMessage());
			}
			
			// No results - Global process aborted
			if(count($this->_as_links_step2)==0)
			{
				throw new JobGenericException("No result found at the end of preprocessing thread. global process finished!");
			}
			
			// if a file with same name existing in final directory
			$l_i_continueIfFileExists = $this->getPropertieValue("JOBPRE_EXCLUDE_FILE_EXISTING");
			// 0 => Abort if a file found
			// 1 => continue
			$l_as_arrayTmp = array();
			$l_i_notvalid = 0;
			foreach($this->_as_links_step2 as $l_s_value)
			{
				
				$l_s_filenameFromURL = Tools::getFilenameFromURL($l_s_value);
				$l_s_supposedFileNameOfTarget = $this->getPropertieValue("JOBPOST_TARGET_PATH").$l_s_filenameFromURL;
				JobsManager::getLogManager()->addLogInformation($this,"Check existing of '$l_s_supposedFileNameOfTarget' file before dl it.");
				if(!is_null($l_s_filenameFromURL) && file_exists($l_s_supposedFileNameOfTarget))
				{
					JobsManager::getLogManager()->addLogError($this,"File '$l_s_supposedFileNameOfTarget' already exists !");
					$l_i_notvalid++;
				}
				else 
					$l_as_arrayTmp[] = $l_s_value;
			}
			
			// At least one file already existing in target.
			if($l_i_notvalid != 0 && $l_i_continueIfFileExists == 0)
				throw new JobGenericException("File already downloaded found. Process aborted.");
			else 
			{
				JobsManager::getLogManager()->addLogInformation($this,"After cleaning of already downloaded file, ".count($l_as_arrayTmp)." remaining.");
				
				$this->_as_links_step2 = array();
				foreach($l_as_arrayTmp as $l_s_valueTest)
				{
					JobsManager::getLogManager()->addLogInformation($this,"Link '".$l_s_valueTest."' OK.");
					array_push($this->_as_links_step2,$l_s_valueTest);
				}
				
			}
		}
		catch(Exception $e)
		{
			throw $e;
		}
		JobsManager::getLogManager()->addLogInformation($this, "Pre-processing - END.");
	}	
	
	/**
	 * RunJob - Main Process
	 * 
	 * @see IRunnableJob::RunJob()
	 */
	function RunJob()
	{
		JobsManager::getLogManager()->addLogTitle("Run - START - Download links.");
		
		// Download part
		if(count($this->_as_links_step2) > 0)
		{				
			$l_o_objTool = new DownloadFileJobTool($this);
			foreach($this->_as_links_step2 as $l_s_urltmp)
			{
				JobsManager::getLogManager()->addLogInformation($this, "Management of URL : '".$l_s_urltmp."'");
				JobsManager::getLogManager()->flushAllLogsToStdout();
				
				// Download asked
				if(intval($this->getPropertieValue("JOBRUN_REAL_DL"))>0)
				{
					// Prepare output dir
					JobsManager::getLogManager()->addLogInformation($this, "Preparing target dir : '".$this->getPropertieValue("JOBRUN_TARGET_PATH")."'");
					php_jobs_launcher::prepareDir($this->getPropertieValue("JOBRUN_TARGET_PATH"),true);
					
					// Outputfile
					$l_s_filenameOut = $this->getFilenameFromURL($l_s_urltmp);
					$l_s_completeFilePathOut = sprintf($this->getPropertieValue("JOBRUN_FILENAME_TMP_STEP_RUN"),$this->getPropertieValue("JOBRUN_TARGET_PATH").$l_s_filenameOut);
					
					// Output file already exists
					if(php_jobs_launcher::checkFileExistance($this->getPropertieValue("JOBRUN_TARGET_PATH"), $l_s_filenameOut))
					{
						JobsManager::getLogManager()->addLogInformation($this, "Output file : '".$l_s_completeFilePathOut."' already exists ! Download ignored.");
					}
					else 
					{
						JobsManager::getLogManager()->addLogInformation($this, "Starting download of '".$l_s_urltmp."' to '".$l_s_completeFilePathOut."'.");
						try{
							$l_as_options = array();
							$l_as_options["INPUT_URL"] = $l_s_urltmp;
							$l_as_options["OUPUT_FILEPATH"] = $l_s_completeFilePathOut;
							$l_as_options["POST_DATA"] = array();
							$l_o_objTool->RunJobTool($l_as_options);
							
							JobsManager::getLogManager()->addLogInformation($this, "Download of '".$l_s_urltmp."' successfully done !");
						 	$this->_as_filename_step3[] = array($l_s_urltmp,$l_s_completeFilePathOut);
						}
						catch(Exception $e)
						{
							JobsManager::getLogManager()->addLogInformation($this,"Exception was occured => ".$e->getMessage());
						}
						JobsManager::getLogManager()->addLogInformation($this, "Ending download of '".$l_s_urltmp."' to '".$l_s_completeFilePathOut."'.");
					}
				}
				else 
					JobsManager::getLogManager()->addLogInformation($this, "Real download of URL : '".$l_s_urltmp."' desactivated.");
			}
		}
		JobsManager::getLogManager()->addLogInformation($this,"Run - STOP");
	}
	
	/**
	 * (non-PHPdoc)
	 * @see IPostProcessedJob::PostProcessJob()
	 */
	function PostProcessJob()
	{
		JobsManager::getLogManager()->addLogTitle("Post processing - START - Move files to target folder.");
		// for each element of table
		if(!is_null($this->_as_filename_step3) && ! empty($this->_as_filename_step3))
		{
			foreach ($this->_as_filename_step3 as $l_as_values)
			{
				if(is_array($l_as_values))
				{
					JobsManager::getLogManager()->addLogInformation($this, "Checking file existance '".$l_as_values[1]."'.");
					if(file_exists($l_as_values[1]))
					{
						$l_s_dest = $this->getFilenameFromURL($l_as_values[0]);
						$l_s_completeDest = $this->getPropertieValue("JOBPOST_TARGET_PATH").$l_s_dest;
						JobsManager::getLogManager()->addLogInformation($this, "Renaming '".$l_as_values[1]."' to '".$l_s_completeDest."'.");
						rename($l_as_values[1],$l_s_completeDest);
						JobsManager::getLogManager()->addLogInformation($this, "Renaming done !");						
					}
				}
				else 
					JobsManager::getLogManager()->addLogInformation($this, "1 line ignored.");
			}
		}
		else 
			JobsManager::getLogManager()->addLogWarning($this, "No items downloaded to move ! Post Processing aborted !");
			JobsManager::getLogManager()->addLogInformation($this,"Post processing - END.");
		JobsManager::getLogManager()->addLogBreak();
		return null;
	}
	
	/**
	 * getType - Return AutoDLJob Type Class
	 * (non-PHPdoc)
	 * @see AJob::getType()
	 */
	function getType()
	{
		return __CLASS__;
	}
	
	/**
	 * getFilenameFromURL - Return filename from an URL finishing by filename
	 * 
	 * @param string 	$p_s_url
	 * @return string	FileName found, null if not
	 */
	function getFilenameFromURL($p_s_url)
	{
		$l_s_result = null;
		$l_i_idx = 0;
		$l_i_idx = strrpos($p_s_url, APP_DIR_SEPERATOR);
		
		//echo "test ".$l_i_idx;
		
		if($l_i_idx>0 && $l_i_idx< strlen($p_s_url))
		{
			$l_s_result = substr($p_s_url, $l_i_idx+1);	
		}
		
		//echo "\nresult ".$l_s_result."\n";
		
		return $l_s_result;
	}
	
	/**
	 * getFileExtensionFromURL - Return file extensionfrom an URL finishing by filename
	 *
	 * @param string 	$p_s_url
	 * @return string	File extension  found, null if not
	 */
	function getFileExtensionFromURL($p_s_url)
	{
		$l_s_result = null;
		$l_i_idx = 0;
		$l_s_filename = $this->getFilenameFromURL($p_s_url);
		
		if(!is_null($l_s_filename))
		{
			$l_i_idx = strrpos($l_s_filename, '.');
			
			if($l_i_idx>0 && $l_i_idx<strlen($l_s_filename))
			{
				$l_s_result = substr($l_s_filename, $l_i_idx+1);
			}
		}
		return $l_s_result;		
	}
	
	
	
	
	
	
	
	
	
	
	
	
}



?>